<?php

namespace app\user\controller;

use \app\check\controller\Check;
use app\common\lib\exception\ApiException;
use app\common\lib\Util;
use app\common\model\Recode;
use app\common\model\User;
use app\common\model\Wechat;
use app\log\model\Loginlog;
use think\Cache;
use think\Db;
use think\Exception;
use think\exception\PDOException;

/**
 * 用户登录
 * Class Login
 * @package app\user\controller
 */
class Login extends Check
{
    //        ?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    const ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token';
    //        ?access_token=ACCESS_TOKEN&openid=OPENID
    const GET_USERINFO_URL = 'https://api.weixin.qq.com/sns/userinfo';
    private $appid;
    private $appsecret;

    protected function _initialize()
    {
        parent::_initialize();// 不需要登录
        $this->appid = config('wechat.wechat_appid');
        $this->appsecret = config('wechat.wechat_appsecret');
    }

    /**
     * 客户端微信登录
     * @return \think\response\Json
     * @throws Exception
     * @throws PDOException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function wechat()
    {
        $code = input('code');
        if (trim($code) == '')
        {
            $user_info_json = input('userinfo');
            if ($user_info_json)
            {
                $user_info = json_decode($user_info_json, true);
                if (
                    !isset($user_info['nickname'])
                    || !isset($user_info['sex'])
                    || !isset($user_info['city'])
                    || !isset($user_info['province'])
                    || !isset($user_info['country'])
                    || !isset($user_info['headimgurl'])
                    || !isset($user_info['openid'])
                    || !isset($user_info['unionid'])
                ) return json(['code' => 10215, 'msg' => 'User_info error.']);
            } else
            {
                return json(['code' => 10215, 'msg' => 'User_info error.']);
            }
            $access_token = [
                'access_token' => '',
                'refresh_token' => '',
                'expires_in' => 0,
                'scope' => '',
            ];
        } else
        {
            $access_token_url = self::ACCESS_TOKEN_URL . "?appid=$this->appid&secret=$this->appsecret&code=$code&grant_type=authorization_code";
            $access_token = json_decode($this->curl_get($access_token_url), true);
            if (isset($access_token['errcode'])) return json(['code' => 10216, 'msg' => $access_token['errcode'] . $access_token['errmsg']]);

            $userinfo_url = self::GET_USERINFO_URL . "?access_token=$access_token[access_token]&openid=$access_token[openid]&lang=zh_CN";
            $user_info = json_decode($this->curl_get($userinfo_url), true);
        }


        if (isset($user_info['errcode'])) return json(['code' => 10217, 'msg' => $user_info['errmsg']]);
        $UserModel = new User();
        $WechatModel = new Wechat();

        $user = $WechatModel
            ->alias('w')
            ->field('u.id,w.nickname,u.avatar,u.forbidden,u.email,u.is_first_login,u.uc_id,u.sex,u.has_self_recode,u.uen')
            ->join('app_user u', 'u.id=w.uid', 'INNER')
            ->where(['unionid' => $user_info['unionid']])->find();
        $time = $this->request->time();
        $ip = $this->request->ip();
        if (empty($user))
        {
            $user = [
                'uen' => substr(md5($this->request->time(true) . mt_rand(1, 1000000)), 0, 12),
                'nickname' => $user_info['nickname'],
                'avatar' => $user_info['headimgurl'],
                'reg_time' => $time,
                'reg_ip' => $ip,
                'last_login' => $time,
                'last_ip' => $ip,
                'last_active' => $time,
                'is_first_login' => 1,// 首次登陆标记
                'uc_id' => md5($user_info['unionid'] . $this->request->time(true)),
                'channel'=>Util::getChannelId()
            ];

            if (!$user['id'] = $UserModel->insertGetId($user))
            {
                return json(['code' => 10206, 'data' => [], 'msg' => 'Regeister failed.']);
            }
            $wechat = [
                'uid' => $user['id'],
                'nickname' => $user_info['nickname'],
                'sex' => $user_info['sex'],
                'city' => $user_info['city'],
                'province' => $user_info['province'],
                'country' => $user_info['country'],
                'headimgurl' => $user_info['headimgurl'],
                'openid' => $user_info['openid'],
                'unionid' => $user_info['unionid'],
                'create_time' => $time,
                'update_time' => $time,
                'access_token' => $access_token['access_token'],
                'refresh_token' => $access_token['refresh_token'],
                'expires_in' => $access_token['expires_in'] + $time,
                'scope' => $access_token['scope'],
            ];
            $WechatModel->insertGetId($wechat);// 微信账号记录
            $user['email'] = null;
            $user['avatar'] = null;
            $user['forbidden'] = 0;
            $user['has_self_recode'] = 0;

            // 用户星盘配置初始化  仅当初次登陆时初始化   改成异步操作
            $set = new \app\user\controller\Astroset();
            $set->init($user['id']);
        } else
        {
            if ($user['forbidden'] == 1)
            {
                return json(['code' => 10207, 'data' => [], 'msg' => 'This user login deined.']);
            }
            if (!$user['nickname'])
            {
                try
                {
                    $UserModel
                        ->alias('u')
                        ->join('app_wechat w', 'u.id=w.uid')
                        ->where(['w.unionid' => $user_info['unionid']])
                        ->update(['u.nickname' => $user_info['nickname']]);
                }
                catch (\Exception $e)
                {
                    return show(config('code.error'), $e->getMessage());
                }
            }
            if (!$user['avatar'])
            {
                try
                {
                    $UserModel
                        ->alias('u')
                        ->join('app_wechat w', 'u.id=w.uid')
                        ->where(['w.unionid' => $user_info['unionid']])
                        ->update(['u.avatar' => $user_info['headimgurl']]);
                }
                catch (\Exception $e)
                {
                    return show(config('code.error'), $e->getMessage());
                }

            }
        }

        // 将用户头像和档案头像统一
        $map = ['uid' => $user['id'], 'isself' => 1];
        $rea = (new Recode())->field('avatar')->where($map)->find();
        if ($rea)
        {
            if (strcmp($rea['avatar'], $user['avatar']) !== 0)
            {
                $UserModel->where('id', $user['id'])->update(['avatar' => $rea['avatar']]);
            }
        }

        $UserModel->check_uen($user);

        // 记录登陆日志  改成异步操作
        (new Loginlog())->insertGetId([
            'uid' => $user['id'],
            'login_time' => $time,
            'login_type' => 1,
            'login_ip' => $ip,
        ]);

        return show(config('code.success'), '登录成功', $user);
    }

    public function sina()
    {

    }

    /**
     * 发起GET请求
     * @param string $url
     * @return mixed
     */
    protected function curl_get($url = '')
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }
}
